package com.salesmanager.web.utils;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
  
public class ImageUtil {
	private static String KEY_WIDTH = "WIDTH";
	private static String KEY_HEIGHT = "HEIGHT";
	private static String KEY_DRAW_X = "DRAW_X";
	private static String KEY_DRAW_Y = "DRAW_Y";
	
	private static Map<String, Integer> calcSize(int iWidth, int iHeight, int tWidth, int tHeight, boolean needCut) throws Exception{
		if (iWidth <= 0||iHeight <= 0||tWidth <= 0||tHeight <= 0){
			throw new Exception("Size has to be greater than 0.");
		}
		
		Map<String, Integer> size = new HashMap<String, Integer>();
		double iRatio = iWidth*1d/iHeight;
		double tRatio = tWidth*1d/tHeight;
		
		boolean flag = iRatio>=tRatio?!needCut:needCut;
		
		if(flag){
			size.put(KEY_WIDTH, tWidth);
			size.put(KEY_HEIGHT, (tWidth*iHeight/iWidth));
			size.put(KEY_DRAW_X, 0);
			size.put(KEY_DRAW_Y, (tHeight - (tWidth*iHeight/iWidth)) / 2);
		} else {
			size.put(KEY_WIDTH, tHeight*iWidth/iHeight);
			size.put(KEY_HEIGHT, tHeight);
			size.put(KEY_DRAW_X, (tWidth - (tHeight*iWidth/iHeight)) / 2);
			size.put(KEY_DRAW_Y, 0);
		}

		return size;
	}
	/**
	 * 文件缩放
	 * 
	 * @param originalFile 源文件
	 * @param resizedFile 目标文件
	 * @param tWidth 缩放后宽度(px)
	 * @param tHeight 缩放后高度(px)
	 * @param needCut 是否剪裁文件多余部分，如不剪裁，剩余部分补白处理
	 * @param quality 文件质量参数(default : 0.7f)
	 * @return MD5 code
	 */
	public static void resize(File originalFile, File resizedFile, int tWidth, int tHeight, boolean needCut, float quality) throws Exception {
		if (quality < 0 || quality > 1) {
			quality = 0.7f;
		}

		ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
		Image i = ii.getImage();

		int iWidth = i.getWidth(null);
		int iHeight = i.getHeight(null);
		
		Map<String, Integer> targetSize = calcSize(iWidth, iHeight, tWidth, tHeight, needCut);
		
		Image resizedImage = i.getScaledInstance(targetSize.get(KEY_WIDTH), targetSize.get(KEY_HEIGHT), Image.SCALE_SMOOTH);

		// This code ensures that all the pixels in the image are loaded.  
		Image itemp = new ImageIcon(resizedImage).getImage();
  
		// Create the buffered image.  
		BufferedImage bufferedImage = new BufferedImage(tWidth,  tHeight, BufferedImage.TYPE_INT_RGB);
  
		// Copy image to buffered image.  
		Graphics g = bufferedImage.createGraphics();
  
		// Clear background and paint the image.  
		g.setColor(Color.white);
		g.fillRect(0, 0, tWidth, tHeight);
		g.drawImage(itemp, targetSize.get(KEY_DRAW_X), targetSize.get(KEY_DRAW_Y), itemp.getWidth(null), itemp.getHeight(null), Color.white, null);
		g.dispose();

		// Soften.  
		float softenFactor = 0.05f;
		
		float[] softenArray = { 0, softenFactor, 0, 
				softenFactor,  1 - (softenFactor * 4), softenFactor,
				0, softenFactor, 0 };//3*3 array
		Kernel kernel = new Kernel(3, 3, softenArray);
		ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
		bufferedImage = cOp.filter(bufferedImage, null);
		
		ImageIO.write(bufferedImage, "jpg", resizedFile);
	}

	/**
	 * 获取单个文件的MD5值！
	 * 
	 * @param file
	 * @return MD5 code
	 */
	public static String getFileMD5(File file) throws Exception{
		if (!file.isFile()) {
			throw new Exception("file does not exist");
		}
		MessageDigest digest = null;
		FileInputStream in = null;
		byte buffer[] = new byte[1024];
		int len;
		try {
			digest = MessageDigest.getInstance("MD5");
			in = new FileInputStream(file);
			while ((len = in.read(buffer, 0, 1024)) != -1) {
				digest.update(buffer, 0, len);
			}
		} catch (Exception e) {
			throw new Exception("get errors when calculate MD5");
		} finally {
			in.close();
		}
		BigInteger bigInt = new BigInteger(1, digest.digest());
		return bigInt.toString(16);
	}

    /**
     * 根据code 生成商品图片名称
     * @param productCode
     * @return
     */
    public static String getProductImageName(String productCode,String suffix){
        return productCode+"_"+System.currentTimeMillis()+"."+suffix;
    }

    /**
     *
     * @param code
     * @return
     */
    public static String getImageName(String code,String suffix){
        return code + "_" + System.currentTimeMillis()+"."+suffix;
    }

	public static void main(String[] args) {
		File originalImage = new File("D:\\testimg\\1.jpg");
		try {
			resize(originalImage, new File("D:\\testimg\\1-1.jpg"),500,500, false, 0.7f);
			resize(originalImage, new File("D:\\testimg\\1-2.jpg"),500,500, true, 0.7f);
//			resize(originalImage, new File("E:\\img\\1-2.jpg"),500,500, false, 1f);
//			resize(originalImage, new File("E:\\img\\1-3.jpg"),500,500, true, 0.7f);
//			resize(originalImage, new File("E:\\img\\1-4.jpg"),500,500, true, 1f);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
